package com.example.patentback.service.impl;

import com.example.patentback.dao.*;
import com.example.patentback.entity.*;
import com.example.patentback.service.SysUserService;
import com.example.patentback.util.Const;
import com.example.patentback.util.RedisUtil;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysUserRoleMapper userRoleMapper;

    @Autowired
    SysRoleMapper sysRoleMapper;

    @Autowired
    SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    SysMenuMapper sysMenuMapper;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public SysUser getByUsername(String username) {
        Example example = new Example(SysUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", username);
        List<SysUser> sysUsers = sysUserMapper.selectByExample(example);
        if (sysUsers.isEmpty()) {
            return null;
        } else {
            return sysUsers.get(0);
        }
    }

    @Override
    public String getUserAuthorityInfo(Long userId) {
        //获取角色
        String authority = "";
        if (redisUtil.hasKey("GrantedAuthority:" + userId)) {
            authority = (String) redisUtil.get("GrantedAuthority:" + userId);
        } else {

            Example example = new Example(SysUserRole.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("userId", userId);
            List<SysUserRole> sysUserRoles = userRoleMapper.selectByExample(example);
            List<SysRole> sysRoles = new ArrayList<>();
            for (SysUserRole ur : sysUserRoles) {
                Example example1 = new Example(SysRole.class);
                Example.Criteria criteria1 = example1.createCriteria();
                criteria1.andEqualTo("id", ur.getRoleId());
                List<SysRole> sysRoles1 = sysRoleMapper.selectByExample(example1);
                sysRoles.add(sysRoles1.get(0));
            }
            if (sysRoles.size() > 0) {
                String roleCodes = sysRoles.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
                authority = roleCodes.concat(",");
            }
            //获取菜单
            List<SysRoleMenu> menus = sysRoleMenuMapper.selectMenusByUserId(userId);
            List<Long> menuIds = new ArrayList<>();
            for (SysRoleMenu rm : menus) {
                menuIds.add(rm.getMenuId());
            }
            Example example2 = new Example(SysRole.class);
            Example.Criteria criteria2 = example2.createCriteria();
            criteria2.andIn("id", menuIds);
            List<SysMenu> sysMenus = sysMenuMapper.selectByExample(example2);
            String menuPerms = sysMenus.stream().map(m -> m.getPerms()).collect(Collectors.joining(","));
            authority = authority.concat(menuPerms);

            redisUtil.set("GrantedAuthority:" + userId, authority, 60 * 60 * 4);
        }

        return authority;
    }

    @Override
    public void clearUserAuthorityInfo(Long userId) {
        redisUtil.del("GrantedAuthority:" + userId);
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {
        Example example = new Example(SysUserRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleId", roleId);
        List<SysUserRole> sysUserRoles = userRoleMapper.selectByExample(example);
        sysUserRoles.forEach(ur -> {
            this.clearUserAuthorityInfo(ur.getUserId());
        });
    }

    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        Example example = new Example(SysRoleMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("menuId", menuId);
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuMapper.selectByExample(example);
        sysRoleMenus.forEach(rm -> {
            this.clearUserAuthorityInfoByRoleId(rm.getRoleId());
        });
    }

    @Override
    public SysUser selectById(Long id) {
        return sysUserMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<SysUser> selectByUsername(String username, int current, int size) {
        int pageNum = current;
        int pageSize = size;
        int start = (pageNum - 1) * pageSize;
        RowBounds rowBounds = new RowBounds(start, pageSize);
        if (username == null) {
            return sysUserMapper.selectByRowBounds(new SysUser(), rowBounds);
        } else {
            Example example = new Example(SysUser.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.orLike("username", "%" + username + "%");
            return sysUserMapper.selectByExampleAndRowBounds(example, rowBounds);
        }
    }

    @Override
    public SysUser saveSysUser(SysUser sysUser) {
        sysUser.setCreated(new Date());
        sysUser.setStatu(Const.STATUS_ON);
        String password = bCryptPasswordEncoder.encode(Const.DEFULT_PASSWORD);
        sysUser.setPassword(password);
        sysUser.setAvatar(Const.DEFULT_AVATAR);
        sysUserMapper.insert(sysUser);
        return sysUser;
    }

    @Override
    public SysUser updateUser(SysUser sysUser) {
        sysUser.setUpdated(new Date());
        sysUserMapper.updateByPrimaryKey(sysUser);
        return sysUser;
    }

    @Override
    public int deleteUser(Long[] ids) {
        Example example = new Example(SysUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", Arrays.asList(ids));
        return sysUserMapper.deleteByExample(example);
    }

    @Override
    public int resetPassword(Long userId) {
        SysUser sysUser = this.selectById(userId);
        sysUser.setPassword(bCryptPasswordEncoder.encode(Const.DEFULT_PASSWORD));
        sysUser.setUpdated(new Date());
        return sysUserMapper.updateByPrimaryKey(sysUser);
    }

    @Override
    public SysUser insert(RegisterDto registerDto) {
        Example example = new Example(SysUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username",registerDto.getUsername());
        List<SysUser> sysUsers = sysUserMapper.selectByExample(example);
        if(sysUsers.size()>0){
            return null;
        }
        SysUser sysUser = new SysUser();
        sysUser.setUsername(registerDto.getUsername());
        sysUser.setPassword(bCryptPasswordEncoder.encode(registerDto.getPassword()));
        sysUser.setCreated(new Date());
        sysUser.setAvatar("2.png");
        sysUser.setStatu(1);
        sysUser.setCity("上海");
        sysUser.setEmail("123@qq.com");
        int insert = sysUserMapper.insert(sysUser);
        if(insert>0){
            sysUser.setPassword("加密");
        }
        return sysUser;
    }
}
